home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
LIBRARY
/
PCTV3N3
/
PTRMATH.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-10-14
|
4KB
|
95 lines
unit ptrmath;
{*************************************************************
* A unit of functions for directly manipulating TP pointers. *
* Requires a version of TP with the built-in assembler. *
* (C) Daniel A. Bronstein, Michigan State University, 1991. *
* May be freely used provided attribution is made. *
*************************************************************}
Interface
function ptrinc(p:pointer;w:word):pointer;
function ptrdec(p:pointer;w:word):pointer;
function baseptr(p:pointer):pointer;
Implementation
{************************************
* PTRINC - Inc a pointer by a word. *
************************************}
function ptrinc(p:pointer;w:word):pointer;assembler;
asm
les di,p {Load pointer in ES:DI and}
mov bx,di {save DI in BX for later use.}
add di,w {Add w to DI and see if we}
cmp di,bx {have wrapped around.}
ja @xit {If not, all ok, so exit, else}
xor di,di {return a nil pointer by 0'ing}
mov es,di {DI and ES.}
@xit:
mov ax,di {Return the pointer in}
mov dx,es {DX:AX.}
end;
{************************************
* PTRDEC - Dec a pointer by a word. *
************************************}
function ptrdec(p:pointer;w:word):pointer;assembler;
asm
les di,p {Same system as PTRINC.}
mov bx,di
sub di,w
cmp di,bx
jb @xit
xor di,di
mov es,di
@xit:
mov ax,di
mov dx,es
end;
{*******************************************************************
* BASEPTR - Create a base pointer - Return pointer in the form *
* $XXXX:$000X; e.g., $66F3:$800A = $6EF3:$000A. This is very *
* useful as some versions of DOS on some machines may not always *
* return allocated memory in this format, which allows for easy *
* wrap-around checks in PTRINC and PTRDEC. Does not work if the *
* original segment is greater than $F000 as it might itself *
* wrap-around in that case, but since TP cannot allocate memory in *
* the $F000 segment that should not be a problem. *
* Algorithm is: *
* power = 12 *
* divr = 2^power *
* while offset > 16 *
* quot = offset / divr *
* offset = offset - (quot * divr) *
* power = power - 4 *
* divr = 2^power *
* segment = segment + (quot * divr) *
*******************************************************************}
function baseptr(p:pointer):pointer;assembler;
asm
les di,p {Load the ptr and}
mov dx,es {move ES to DX.}
cmp dx,0F000h {If ES(DX) > $F000, danger of}
ja @xit {wrap-around, so exit.}
mov cl,12 {Prepare CL for SHL & SHR.}
@loop:
cmp di,10h {If DI < 16 then done,}
jb @xit {so exit;}
mov ax,di {Move DI to AX and}
shr ax,cl {divide by 2^CL (4096,256,16),}
mov bx,ax {move AX to BX and}
shl bx,cl {multiply by 2^CL then}
sub di,bx {subtract from DI.}
sub cl,4 {Reduce CL by 4,}
shl ax,cl {multiply AX by 2^CL}
add dx,ax {and add it to DX,}
jmp @loop {then loop back.}
@xit:
mov ax,di {Return the ptr in DX:AX.}
end;
end.